package com.example.text.app



import android.Manifest
import android.app.Activity
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.ContentResolver
import android.content.Context
import android.content.Intent
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.database.Cursor
import android.graphics.ColorMatrix
import android.graphics.ColorMatrixColorFilter
import android.graphics.Point
import android.graphics.Typeface
import android.graphics.drawable.Drawable
import android.location.LocationManager
import android.net.Uri
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.os.SystemClock
import android.provider.MediaStore
import android.provider.Settings
import android.text.Editable
import android.text.TextWatcher
import android.util.TypedValue
import android.view.View
import android.view.WindowManager
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat
import androidx.core.text.isDigitsOnly
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.onFailure
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flow
import me.jessyan.autosize.utils.AutoSizeUtils
import java.io.File
import java.io.IOException
import java.io.PrintWriter
import java.io.StringWriter
import java.lang.reflect.Field
import java.lang.reflect.InvocationTargetException
import java.util.regex.Pattern
import kotlin.random.Random


val appContext: Context
    get() = App.getAppContext()


val screenSize: Point
    get() {
        val outSize = Point()
        val w = appContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        w.defaultDisplay.getSize(outSize)
        return outSize
    }
val Float.dp: Float
    get() = AutoSizeUtils.dp2px(appContext, this).toFloat()


val Int.dp: Int
    get() = AutoSizeUtils.dp2px(appContext, this.toFloat())


val Float.sp: Float
    get() = AutoSizeUtils.sp2px(appContext, this).toFloat()


val Int.sp: Int
    get() = AutoSizeUtils.sp2px(appContext, this.toFloat())

// 格式化小数，默认保留两位
fun Float.formatDecimal(size: Int = 2): String {
    return String.format("%.${size}f", this)
}

fun Double.formatDecimal(size: Int = 2): String {
    return String.format("%.${size}f", this)
}

/** 将价格格式化成人民币 */
fun Double.formatCNYPrice(): String {
    val cny = "¥${this.formatDecimal(2)}"
    return cny.replace(".00", "")
}

/** 将hms 转成HH:mm:ss */
fun Long.formatTimeTwo(): String {
    return if (this < 10) "0$this" else this.toString()
}

/**
 * 如果浮点数是整数，格式成整数，否则格式化成小数
 * 1.99 -> 1.99
 * 1.3 --> 1.3
 * 1.0 --> 1
 * 0.0 --> 0
 **/
fun Float.format2IntOrFloatStr(): String {
    if (this == 0f) return "0"
    val s = this.toString()
    if (s.endsWith(".0") || s.endsWith(".00")) {
        return this.toInt().toString()
    }
    return this.toString()
}

fun Int.formatCount(): String {
    if (this >= 10000) {
        val w = this / 10000
        return "${w}w+"
    }
    return this.toString()
}

fun Long.formatCount(): String {
    if (this >= 10000) {
        val w = this / 10000
        return "${w}w+"
    }
    return this.toString()
}

/** 使ImageView图片变灰 */
//fun ImageView.makeGrayImage(gray: Boolean) {
//    try {
//        val matrix = ColorMatrix()
//        if (gray) matrix.setSaturation(0f) else matrix.setSaturation(1f)
//        val filter = ColorMatrixColorFilter(matrix)
//        this.colorFilter = filter
//    } catch (e: Exception) {
//        e.printStackTrace()
//        JLogUtil.e(e)
//    }
//}

/** 手机号脱敏 */
fun String.desensitization(): String {
    if (this.isEmpty() || this.length != 11 || !this.isDigitsOnly()) return this
    return this.substring(0, 3) + "****" + this.substring(7, 11)
}

//获取属性值
fun getAttrValue(context: Context, attrId: Int): Int {
    val typedValue = TypedValue()
    context.theme.resolveAttribute(attrId, typedValue, true)
    return typedValue.resourceId
}

fun <T> Flow<T>.throttleFirst(thresholdMillis: Long) = flow {
    var lastTime = 0L
    collect { upstream ->
        val currentTime = SystemClock.elapsedRealtime()
        if (currentTime - lastTime >= thresholdMillis) {
            lastTime = currentTime
            emit(upstream)
        }
    }
}

// 监听输入框内容变化后
fun EditText.watchAfterTextChanged(afterTextChanged: (s: Editable?) -> Unit) {
    this.addTextChangedListener(object : TextWatcher {
        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}

        override fun afterTextChanged(s: Editable?) {
            afterTextChanged.invoke(s)
        }
    })
}

//fun Fragment.handleRequestPermissions(
//    vararg permissions: String,
//    desc: String,
//    onGranted: () -> Unit,
//    onDenied: (() -> Unit)? = null,
//    onDeniedWithoutRequest: (() -> Unit)? = null
//) {
//    val hasPermissions = RxPermissions(this).hasPermissions(*permissions)
//    if (hasPermissions) {
//        onGranted.invoke()
//        return
//    }
//    //显示说明
//    MessageNoticeDialog(message = desc, onConfirmClick = {
//        //申请权限
//        val d = RxPermissions(this).requestEachCombined(*permissions).subscribe { permission ->
//            if (!permission.denied && permission.granted) {
//                //同意授予
//                onGranted.invoke()
//            } else if (permission.denied && !permission.granted) {
//                //拒绝
//                onDenied?.invoke()
//            } else if (!permission.denied && !permission.granted) {
//                //未询问,被拒绝
//                onDeniedWithoutRequest?.invoke()
//            } else {
//
//            }
//        }
//    }, onCancelClick = {
//        onDenied?.invoke()
//    }).show(this.childFragmentManager)
//}

//fun Fragment.handleRequestPermissions(
//    vararg permissions: String,
//    onGranted: () -> Unit,
//    onDenied: (() -> Unit)? = null,
//    onDeniedWithoutRequest: (() -> Unit)? = null
//) {
//    val hasPermissions = RxPermissions(this).hasPermissions(*permissions)
//    if (hasPermissions) {
//        onGranted.invoke()
//        return
//    }
//    //申请权限
//    val d = RxPermissions(this).requestEachCombined(*permissions).subscribe { permission ->
//        if (!permission.denied && permission.granted) {
//            //同意授予
//            onGranted.invoke()
//        } else if (permission.denied && !permission.granted) {
//            //拒绝
//            onDenied?.invoke()
//        } else if (!permission.denied && !permission.granted) {
//            //未询问,被拒绝
//            onDeniedWithoutRequest?.invoke()
//        } else {
//
//        }
//    }
//}


//fun FragmentActivity.handleRequestPermissions(
//    vararg permissions: String,
//    desc: String,
//    onGranted: () -> Unit,
//    onDenied: (() -> Unit)? = null,
//    onDeniedWithoutRequest: (() -> Unit)? = null,
//    confirmText: String = "确认"
//) {
//    val hasPermissions = RxPermissions(this).hasPermissions(*permissions)
//    if (hasPermissions) {
//        onGranted.invoke()
//        return
//    }
//    //显示说明
//    MessageNoticeDialog(message = desc, confirmText = confirmText, onConfirmClick = {
//        //申请权限
//        val d = RxPermissions(this).requestEachCombined(*permissions).subscribe { permission ->
//            if (!permission.denied && permission.granted) {
//                //同意授予
//                onGranted.invoke()
//            } else if (permission.denied && !permission.granted) {
//                //拒绝
//                onDenied?.invoke()
//            } else if (!permission.denied && !permission.granted) {
//                //未询问,被拒绝
//                onDeniedWithoutRequest?.invoke()
//            } else {
//
//            }
//        }
//    }, onCancelClick = {
//        onDenied?.invoke()
//    }).show(this.supportFragmentManager, MessageNoticeDialog.TAG)
//}

//fun FragmentActivity.handleRequestPermissions(
//    vararg permissions: String,
//    onGranted: () -> Unit,
//    onDenied: (() -> Unit)? = null,
//    onDeniedWithoutRequest: (() -> Unit)? = null
//) {
//    val hasPermissions = RxPermissions(this).hasPermissions(*permissions)
//    if (hasPermissions) {
//        onGranted.invoke()
//        return
//    }
//    //申请权限
//    val d = RxPermissions(this).requestEachCombined(*permissions).subscribe { permission ->
//        if (!permission.denied && permission.granted) {
//            //同意授予
//            onGranted.invoke()
//        } else if (permission.denied && !permission.granted) {
//            //拒绝
//            onDenied?.invoke()
//        } else if (!permission.denied && !permission.granted) {
//            //未询问,被拒绝
//            onDeniedWithoutRequest?.invoke()
//        } else {
//
//        }
//    }
//}

//按键消抖
fun View.clickFlow() = callbackFlow {
    setOnClickListener {
        trySend(Unit).onFailure { e -> e?.printStackTrace() }
    }
    awaitClose { setOnClickListener(null) }
}


//fun Flow<ApiException>.handleException() = catch { cause ->
//    val apiException = ApiException.getApiException(cause)
//    emit(apiException)
//}

////全局分页的配置
//const val DEFAULT_PAGE_SIZE = 10
//const val INITIAL_LOAD_SIZE = 10
//val globalPagingConfig: PagingConfig
//    get() {
//
//        return PagingConfig(
//            pageSize = DEFAULT_PAGE_SIZE,
//            enablePlaceholders = true,
//            initialLoadSize = INITIAL_LOAD_SIZE,
//            prefetchDistance = DEFAULT_PAGE_SIZE
//        )
//    }

//定位功能是否开启
fun getGpsStatus(): Boolean {
    val lm: LocationManager = appContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
    return lm.isProviderEnabled(LocationManager.GPS_PROVIDER)
}

//fun createMapBounds(latA: Double, lngA: Double, latB: Double, lngB: Double): LatLngBounds? {
//    val northeastLatLng: LatLng
//    val southwestLatLng: LatLng
//    val topLat: Double
//    val topLng: Double
//    val bottomLat: Double
//    val bottomLng: Double
//    if (latA >= latB) {
//        topLat = latA
//        bottomLat = latB
//    } else {
//        topLat = latB
//        bottomLat = latA
//    }
//    if (lngA >= lngB) {
//        topLng = lngA
//        bottomLng = lngB
//    } else {
//        topLng = lngB
//        bottomLng = lngA
//    }
//    northeastLatLng = LatLng(topLat, topLng)
//    southwestLatLng = LatLng(bottomLat, bottomLng)
//    return LatLngBounds(southwestLatLng, northeastLatLng)
//}


//获取当前显示的Activity
fun getShowingActivity(): Activity? {
    var activityThreadClass: Class<*>? = null
    try {
        activityThreadClass = Class.forName("android.app.ActivityThread")
        val activityThread = activityThreadClass.getMethod("currentActivityThread").invoke(null)
        val activitiesField: Field = activityThreadClass.getDeclaredField("mActivities")
        activitiesField.isAccessible = true
        val activities = activitiesField.get(activityThread) as Map<*, *>
        for (activityRecord in activities.values) {
            val activityRecordClass: Class<*> = activityRecord!!.javaClass
            val pausedField: Field = activityRecordClass.getDeclaredField("paused")
            pausedField.isAccessible = true
            if (!pausedField.getBoolean(activityRecord)) {
                val activityField: Field = activityRecordClass.getDeclaredField("activity")
                activityField.isAccessible = true
                return activityField.get(activityRecord) as Activity
            }
        }
    } catch (e: ClassNotFoundException) {
        e.printStackTrace()
    } catch (e: NoSuchMethodException) {
        e.printStackTrace()
    } catch (e: IllegalAccessException) {
        e.printStackTrace()
    } catch (e: InvocationTargetException) {
        e.printStackTrace()
    } catch (e: NoSuchFieldException) {
        e.printStackTrace()
    }
    return null
}

fun Uri.toPath(contentResolver: ContentResolver): String {
    val imagePath: String
    val proj = arrayOf(MediaStore.Images.Media.DATA)
    val cursor: Cursor? = contentResolver.query(this, proj, null, null, null)
    imagePath = if (cursor == null) ({
        this.path
    }).toString() else {
        val index: Int = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
        cursor.moveToFirst()
        cursor.getString(index)
    }
    cursor?.close()
    return imagePath
}

fun getVersionCode(mContext: Context): Int {
    var versionCode = 0
    try {
        //获取软件版本号，对应AndroidManifest.xml下android:versionCode
        versionCode = mContext.packageManager.getPackageInfo(mContext.packageName, 0).versionCode
    } catch (e: PackageManager.NameNotFoundException) {
        e.printStackTrace()
    }
    return versionCode
}

//阿里云-获取视频首帧图片
fun getAliOSSVideoImage(videoUrl: String): String {
    return "$videoUrl&x-oss-process=video/snapshot,t_1,f_jpg,ar_auto"
}

////帖子分享链接
//fun buildPostShareUrl(postId: String) = BuildConfig.H5_HOST + "mobile/friends_share?id=${postId}"
//
////文章分享链接
//fun buildArticleShareUrl(articleId: String) =
//    BuildConfig.H5_HOST + "mobile/friends_share_w?id=${articleId}"
//
////指南分享链接
//fun buildGuideShareUrl(guideId: String) = BuildConfig.H5_HOST + "mobile/friends_share_z?id=${guideId}"
//
//// 分享活动链接
//fun buildActShareUrl(actId: String) = "${BuildConfig.H5_HOST}mobile/activity_share?id=${actId}"
//
//// 分享动态链接
//fun buildDynamicShareUrl(dynamicId: String) = "${BuildConfig.H5_HOST}mobile/moments_share?id=${dynamicId}"
//
////路线攻略动态
//fun buildRouteGuideShareUrl(guideId: String) = BuildConfig.H5_HOST + "mobile/line_share?id=${guideId}"
//
////知识库动态
//fun buildWikiShareUrl(id: String) = BuildConfig.H5_HOST + "mobile/repository_share?id=${id}"
//
////咨询分享
//fun buildInformationShareUrl(id: String) = BuildConfig.H5_HOST + "mobile/information_share?id=${id}"

/** 判断字符串是否只包含中英文 */
fun String.isChineseOrLetter(): Boolean {
    val arr = this.toCharArray()

    val p1 = Pattern.compile("[A-Za-z]")
    val p2 = Pattern.compile("[\u4e00-\u9fa5]")
    for (c in arr) {
        // 这里的isLetter 包含了中英文
        val m1 = p1.matcher(c.toString())
        if (m1.find()) {
            continue
        } else {
            val m2 = p2.matcher(c.toString())
            if (m2.find()) {
                continue
            } else {
                return false
            }
        }
    }
    return true
}

/**
 * 处理url参数 转成 map
 */
fun getUrlParams(param: String): Map<String, Any?> {
    val map: MutableMap<String, Any> = HashMap(0)
    if (param.isBlank()) {
        return map
    }
    val params = param.split("&".toRegex()).toTypedArray()
    for (i in params.indices) {
        val p = params[i].split("=".toRegex()).toTypedArray()
        if (p.size == 2) {
            map[p[0]] = p[1]
        }
    }
    return map
}


/**
 * 是否选中上传的文件超过限制
 */

//fun isFileOverLimit(files: List<LocalMedia?>): String? {
//    return run {
//        var overLimitMessage: String? = null
//        files.forEach {
//            it ?: return@forEach
//            val fileMB = it.size.toFloat() / 1024 / 1024
//            if (it.mimeType?.contains(MimeTypes.BASE_TYPE_VIDEO) == true) {
//                //视频
//                if (fileMB > AppConfig.VIDEO_SIZE_LIMIT) {
//                    overLimitMessage = String.format("视频超过限制大小%.1fMB", AppConfig.VIDEO_SIZE_LIMIT)
//                    return@run overLimitMessage
//                }
//            } else {
//
//                if (fileMB > AppConfig.IMAGE_SIZE_LIMIT) {
//                    overLimitMessage = String.format("图片超过限制大小%.1fMB", AppConfig.IMAGE_SIZE_LIMIT)
//                    return@run overLimitMessage
//                }
//            }
//        }
//        return overLimitMessage
//    }
//}

//fun isFileOverLimit(filePath: String, isVideo: Boolean = false): String? {
//    return run {
//        val file = File(filePath)
//        var overLimitMessage: String? = null
//
//        val fileMB = file.length().toFloat() / 1024 / 1024
//        if (isVideo) {
//            //视频
//            if (fileMB > AppConfig.VIDEO_SIZE_LIMIT) {
//                overLimitMessage = String.format("视频超过限制大小%.1fMB", AppConfig.VIDEO_SIZE_LIMIT)
//                return@run overLimitMessage
//            }
//        } else {
//
//            if (fileMB > AppConfig.IMAGE_SIZE_LIMIT) {
//                overLimitMessage = String.format("图片超过限制大小%.1fMB", AppConfig.IMAGE_SIZE_LIMIT)
//                return@run overLimitMessage
//            }
//        }
//
//        return overLimitMessage
//    }
//}

//图标变色
fun tint(drawable: Drawable, color: Int): Drawable {
    val new = DrawableCompat.wrap(drawable).mutate()
    DrawableCompat.setTint(new, ContextCompat.getColor(appContext, color))
    return new
}

fun tintDrawable(drawable: Drawable?, colors: Int): Drawable? {
    val wrappedDrawable = DrawableCompat.wrap(drawable!!).mutate()
    DrawableCompat.setTint(wrappedDrawable, colors)
    return wrappedDrawable
}

//PictureSelector LocalMedia 转 文件路径 , 兼容android10以下
//fun localMedia2FilePath(data: List<LocalMedia?>, contentResolver: ContentResolver): List<String> {
//    val files: List<String> = data.map {
//        it ?: return emptyList()
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
//            //Android10以及以上
//            Uri.parse(it.availablePath).toPath(contentResolver)
//        } else {
//            it.path
//        }
//    }
//    return files
//}

/** TextView加粗并修改字号 */
fun TextView.bold(size: Float = 0f) {
    this.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
    if (size > 0)
        this.textSize = size
}

/** TextView普通并修改字号 */
fun TextView.normal(size: Float = 0f) {
    this.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
    if (size > 0)
        this.textSize = size
}

/** 随机生成一个假手机号,mock时使用 */
fun Random.phoneNumber(): String {
    return "${this.nextInt(130, 199)}${this.nextInt(10000000, 99999999)}"
}

/**
 * Android13申请通知权限
 */
private const val POST_NOTIFICATIONS = "android.permission.POST_NOTIFICATIONS"
//fun requestNotificationPermissionIfOnT(activity: FragmentActivity) {
//    if (Build.VERSION.SDK_INT >= 33) {
//        if (appContext.applicationInfo.targetSdkVersion == 32) {
//            requestPostNotification()
//        } else {
//            RxPermissions(activity).requestEach(POST_NOTIFICATIONS).subscribe { permission ->
//                if (!permission.denied && permission.granted) {
//                    //同意授予
//                } else if (permission.denied && !permission.granted) {
//                    //拒绝
//                } else if (!permission.denied && !permission.granted) {
//                    //未询问,被拒绝
//                    // enableNotification()
//                } else {
//
//                }
//            }
//        }
//
//    }
//}

private fun enableNotification(context: Context) {
    try {
        val intent = Intent()
        intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
        intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
        intent.putExtra(Settings.EXTRA_CHANNEL_ID, context.applicationInfo.uid)
        intent.putExtra("app_package", context.packageName)
        intent.putExtra("app_uid", context.applicationInfo.uid)
        context.startActivity(intent)
    } catch (e: java.lang.Exception) {
        e.printStackTrace()
        val intent = Intent()
        intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
        val uri = Uri.fromParts("package", context.packageName, null)
        intent.data = uri
        context.startActivity(intent)
    }
}

//fun requestPostNotification() {
//    if (JPushInterface.isNotificationEnabled(appContext) == 0 && Build.VERSION.SDK_INT >= 33) {
//        val mChannel = NotificationChannel("111", "通知", NotificationManager.IMPORTANCE_DEFAULT)
//        val notificationManager = appContext.getSystemService(AppCompatActivity.NOTIFICATION_SERVICE) as NotificationManager
//        notificationManager.createNotificationChannel(mChannel);
//    }
//}

/**
 * 获取图片视频文件权限
 */
fun getStorageCompatPermission(): Array<String> {
    if (appContext.applicationInfo.targetSdkVersion == 32) {
        return arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
    }
    return if (Build.VERSION.SDK_INT >= 33) {
        arrayOf("android.permission.READ_MEDIA_IMAGES", "android.permission.READ_MEDIA_VIDEO")
    } else {
        arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
    }
}

fun getStackTraceInfo(e: Exception): String? {
    var sw: StringWriter? = null
    var pw: PrintWriter? = null
    return try {
        sw = StringWriter()
        pw = PrintWriter(sw)
        e.printStackTrace(pw) //将出错的栈信息输出到printWriter中
        pw.flush()
        sw.flush()
        sw.toString()
    } catch (ex: Exception) {
        "发生错误"
    } finally {
        if (sw != null) {
            try {
                sw.close()
            } catch (e1: IOException) {
                e1.printStackTrace()
            }
        }
        pw?.close()
    }
}

//fun localMedia2File(localMedia: LocalMedia): File {
//    val file =
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
//            //Android10以及以上
//            File(Uri.parse(localMedia.availablePath).toPath(appContext.contentResolver))
//        } else {
//            File(localMedia.path)
//        }
//
//    return file
//}

fun (() -> Unit).delay(ms: Long) {
    Handler(Looper.getMainLooper()).postDelayed(this, ms)
}

fun isAppInstalled(context: Context, packageName: String): Boolean {
    var packageInfo: PackageInfo? = null
    try {
        packageInfo = context.packageManager.getPackageInfo(packageName, 0)
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return packageInfo != null
}

/** 截断Tab字符串 默认长度5 */
fun String.subTabString(len: Int = 5, tail: String = "..."): String {
    if (this.length > len) {
        return this.substring(0, 5) + tail
    }
    return this
}